/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.server.modules.sys.service.customer.impt;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolationException;

import com.server.common.utils.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
//import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.NumberToTextConverter;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.lowagie.text.pdf.codec.Base64;
import com.monitorjbl.xlsx.StreamingReader;
import com.server.common.beanvalidator.BeanValidators;
import com.server.common.persistence.Page;
import com.server.common.service.CrudService;
import com.server.common.utils.excel.ImportExcel;
import com.server.modules.api.vo.FileVO;
import com.server.modules.sys.entity.User;
import com.server.modules.sys.entity.customer.impt.CustomerImport;
import com.server.modules.sys.entity.customer.impt.CustomerImportLog;
import com.server.modules.sys.entity.material.MaterialUpload;
import com.server.modules.sys.service.batchno.BatchNoService;
import com.server.modules.sys.utils.JdbcUtils;
import com.server.modules.sys.utils.Md5Utils;
import com.server.modules.sys.utils.MyFileUtils;
import com.server.modules.sys.utils.RegexUtils;
import com.server.modules.sys.utils.UserUtils;
import com.server.modules.sys.utils.compress.ExtractUtils;
import com.server.modules.sys.vo.ImportTempObj;
import com.server.modules.sys.zbus.ProducerUtils;
import com.server.modules.sys.common.StaticDefine;
import com.server.modules.sys.dao.customer.impt.CustomerImportDao;

/**
 * 客户导入Service
 * @author 丁光彪
 * @version 2016-10-28
 */
@Service
@Transactional(readOnly = true)
public class CustomerImportService extends CrudService<CustomerImportDao, CustomerImport> {
	@Resource
	private BatchNoService batchNoService;
	
	@Resource
	private CustomerImportLogService customerImportLogService;

    @Resource
    private  SqlSessionFactoryBean sqlSessionFactoryBean;


	public CustomerImport get(String id) {
		return super.get(id);
	}
	
	public Integer getByMobile(String mobile) {
		return dao.getByMobile(mobile);
	}
	
	public List<CustomerImport> findList(CustomerImport customerImport) {
		return super.findList(customerImport);
	}
	
	public Page<CustomerImport> findPage(Page<CustomerImport> page, CustomerImport customerImport) {
		return super.findPage(page, customerImport);
	}
	
	@Transactional(readOnly = false)
	public void save(CustomerImport customerImport) {
		super.save(customerImport);
	}
	
	@Transactional(readOnly = false)
	public void delete(CustomerImport customerImport) {
		super.delete(customerImport);
	}
	@Transactional(readOnly = false)
	public Map<String,Object> batchInsert(MultipartFile file) throws IOException, InstantiationException, IllegalAccessException {
		String contentType = file.getContentType();
		Map<String, Object> ret = new HashMap<String, Object>();
		String name = file.getOriginalFilename();
		//压缩文件单独处理
		if(name.contains("rar")||name.contains("zip")){
			return this.batchInsertCompress(file);
		}
		int successNum = 0;
		int failureNum = 0;
		StringBuilder failureMsg = new StringBuilder();
		String fileName = file.getOriginalFilename();
		Long begin1 = new Date().getTime();
		List<CustomerImport> list=new ArrayList<CustomerImport>();
		Workbook wb = null;
		InputStream is=null;
		 is = file.getInputStream();
		if (org.apache.commons.lang3.StringUtils.isBlank(fileName)){
			throw new RuntimeException("导入文档为空!");
		}else if(fileName.toLowerCase().endsWith("xls")){
			wb = new HSSFWorkbook(is);
		}else if(fileName.toLowerCase().endsWith("xlsx")){
			wb = StreamingReader.builder()
					.rowCacheSize(100)    // number of rows to keep in memory (defaults to 10)
					.bufferSize(4096)     // buffer size to use when reading InputStream to file (defaults to 1024)
					.open(is);
		}else{
			wb = new HSSFWorkbook(is);
			throw new RuntimeException("文档格式不正确!");
		}
     	String type=Excel2Data(list, wb);
		// 插入日志
		CustomerImportLog customerImportLog = new CustomerImportLog();
		customerImportLog.setType(type);
		// 入库
		String batchNO = batchNoService.getBatchNO("1");
		customerImportLog.setBatchNo(batchNO);
		boolean isUploaded = this.uploadFile(file, customerImportLog);
		if (!isUploaded) {
			failureMsg.append("<br/>导入失败：您上传的文件【" + fileName+ "】已经上传过，请不要重复上传哦");
			ret.put("failureMsg", failureMsg);
			ret.put("successNum", successNum);
			ret.put("failureNum", failureNum);
			customerImportLog.setFilename(fileName);
			customerImportLog.setExpectCount(list.size() + "");
			customerImportLog.setValidCount(successNum + "");
			customerImportLog.setRemarks("导入失败：文件【" + fileName+ "】已经上传过");
			customerImportLogService.save(customerImportLog);
			return ret;
		}
		List<CustomerImport> listValid = new ArrayList<CustomerImport>();// 校验后有效的
		//List<CustomerImport> list = ei.getDataList(CustomerImport.class);
		failureNum = validateData(failureNum, failureMsg, listValid, list);
		
		Long end2 = new Date().getTime();
		
		// 开时时间
		Long begin = new Date().getTime();
		
		String filename2 = customerImportLog.getFilename();
		
		successNum = this.BatchInsert(listValid,batchNO,type,filename2);
		if (failureNum > 0) {
			failureMsg.insert(0, "，失败 " + failureNum + " 条客户，导入信息如下：");
		}
		customerImportLog.setExpectCount(list.size() + "");
		customerImportLog.setValidCount(successNum + "");
		customerImportLog.setRemarks("导入成功");
		customerImportLogService.save(customerImportLog);
		// 结束时间
		Long end = new Date().getTime();
		// 耗时
		//ret.put("failureMsg", list.size()-successNum);
		ret.put("successNum", successNum);
		ret.put("failureMsg", failureMsg);
		return ret;
	}

	@Transactional(readOnly = false)
	public Map<String,Object> batchInsert(File file) throws IOException, InstantiationException, IllegalAccessException {
        Map<String, Object> ret = new HashMap<String, Object>();
		String fileName = file.getName();
		//压缩文件单独处理
		int successNum = 0;
		int failureNum = 0;
		StringBuilder failureMsg = new StringBuilder();
		Long begin1 = new Date().getTime();
		List<CustomerImport> list=new ArrayList<CustomerImport>();
		Workbook wb = null;
		InputStream is=null;
		 is =  new FileInputStream(file);
		if (org.apache.commons.lang3.StringUtils.isBlank(fileName)){
			throw new RuntimeException("导入文档为空!");
		}else if(fileName.toLowerCase().endsWith("xls")){
			wb = new HSSFWorkbook(is);
		}else if(fileName.toLowerCase().endsWith("xlsx")){
			wb = StreamingReader.builder()
					.rowCacheSize(100)    // number of rows to keep in memory (defaults to 10)
					.bufferSize(4096)     // buffer size to use when reading InputStream to file (defaults to 1024)
					.open(is);
		}else{
			wb = new HSSFWorkbook(is);
			throw new RuntimeException("文档格式不正确!");
		}
		String type=Excel2Data(list, wb);
		// 插入日志
		CustomerImportLog customerImportLog = new CustomerImportLog();
		customerImportLog.setType(type);
		// 入库
		String batchNO = batchNoService.getBatchNO("1");
		customerImportLog.setBatchNo(batchNO);

		String fileMD5 = Md5Utils.getFileMD5(file);
		int countByMd5 = customerImportLogService.countByMd5(fileMD5);
		//之前上传过
		if(countByMd5>0){
			failureMsg.append("<br/>导入失败：您上传的文件【" + fileName+ "】已经上传过，请不要重复上传哦");
			ret.put("failureMsg", failureMsg);
			ret.put("successNum", successNum);
			ret.put("failureNum", failureNum);
			customerImportLog.preInsert();
			customerImportLog.setExpectCount(list.size() + "");
			customerImportLog.setValidCount(successNum + "");
			customerImportLog.setRemarks("【系统自动导入】：导入失败：文件【" + fileName+ "】已经上传过");
			customerImportLog.setIsNewRecord(true);
            customerImportLog.setMd5(fileMD5);
			customerImportLogService.save(customerImportLog);
			return ret;
		}else{
			customerImportLog.setMd5(fileMD5);
			customerImportLog.setFilename(file.getName());
			customerImportLog.setFilesize(file.length()+"");
			customerImportLog.setFileurl(file.getPath());
		}

		List<CustomerImport> listValid = new ArrayList<CustomerImport>();// 校验后有效的
		failureNum = validateData(failureNum, failureMsg, listValid, list);

		Long end2 = new Date().getTime();
		// 开时时间
		Long begin = new Date().getTime();

		String filename2 = customerImportLog.getFilename();
		successNum = this.BatchInsert(listValid,batchNO,type,filename2);
		if (failureNum > 0) {
			failureMsg.insert(0, "，失败 " + failureNum + " 条客户，导入信息如下：");
		}
		customerImportLog.setExpectCount(list.size() + "");
		customerImportLog.setValidCount(successNum + "");
		customerImportLog.setRemarks("导入成功");
		customerImportLogService.save(customerImportLog);
		// 结束时间
		Long end = new Date().getTime();
		// 耗时
		//ret.put("failureMsg", list.size()-successNum);
		ret.put("successNum", successNum);
		ret.put("failureMsg", failureMsg);
		return ret;
	}

  /*  public int BatchInsert(List<CustomerImport> list, String batchNO, String type, String filename2){
        int successNum=0;
        JdbcUtils jdbcUtils=new JdbcUtils();
        Connection conn = jdbcUtils.getConnection();
        // 开时时间
        Long begin = new Date().getTime();
        // sql前缀
        String prefix = "INSERT INTO t_customer_import(id,name,gender,mobile,tel,company,post,addr,house_property_info,household,car_info,";
        prefix+="plateno,plateno_reg_time,type,batch_no,create_date,create_by,update_date,update_by,remarks,del_flag) VALUES  ";
        int index=0;
        try {
            // 保存sql后缀
            StringBuffer suffix = new StringBuffer();
            // 设置事务为非自动提交
            conn.setAutoCommit(false);
            // Statement st = conn.createStatement();
            // 比起st，pst会更好些
            PreparedStatement pst = conn.prepareStatement("");
            // 外层循环，总提交事务次数
            User user = UserUtils.getUser();
            for (int i = 1; i <= list.size(); i++) {
                // 第次提交步长
                int batchNum=0;
                for (int j = 1; j <= 10000; j++) {
                    // 构建sql后缀
                    if(index<list.size()){
                        CustomerImport customerImport = list.get(index);
                        suffix.append(" (");
                        suffix.append("'").append(IdGen.uuid()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getName())?"":customerImport.getName()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getGender())?"":customerImport.getGender()).append("' , ");
                        suffix.append("'").append(customerImport.getMobile()).append("', ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getTel())?"":customerImport.getTel()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getCompany())?"":customerImport.getCompany()).append(" ', ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getPost())?"":customerImport.getPost()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getAddr())?"":customerImport.getAddr()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getHousePropertyInfo())?"":customerImport.getHousePropertyInfo()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getHousehold())?"":customerImport.getHousehold()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getCarInfo())?"":customerImport.getCarInfo()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getPlateno())?"":customerImport.getPlateno()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getPlatenoRegTime())?"":customerImport.getPlatenoRegTime()).append("' , ");
                        suffix.append("'").append(StringUtils.isBlank(type)?"":type).append("' , ");
                        suffix.append("'").append(batchNO).append("' , ");
                        suffix.append(" SYSDATE() , ");
                        suffix.append("'").append(user.getId()).append("' , ");
                        suffix.append(" SYSDATE() , ");
                        suffix.append("'").append(user.getId()).append("' , ");
                        suffix.append("'").append(filename2).append(" ', ");
                        suffix.append("'").append(StringUtils.isBlank(customerImport.getDelFlag())?null:customerImport.getDelFlag()).append("' ");
                        suffix.append(")");
                        suffix.append(",");
                        index++;
                    }
                }
                // 构建完整sql
                String sql ="";
                if(suffix.length()>0){
                    sql = prefix + suffix.substring(0, suffix.length()-1);
                    // 添加执行sql
                    pst.addBatch(sql);
                    System.out.println(sql);
                    // 执行操作
                    int[] executeBatch = pst.executeBatch();
                    System.out.println(executeBatch);
                    if(executeBatch.length>0){
                        successNum+=batchNum;
                    }
                    // 提交事务
                    conn.commit();
                }
                // 清空上一次添加的数据
                suffix = new StringBuffer();
            }
            // 头等连接
            pst.close();
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        // 结束时间
        Long end = new Date().getTime();
        // 耗时
        System.out.println("插入数据条数 : " + index);
        System.out.println("cast : " + (end - begin) / 1000 + " s");
        return successNum;
    }
    */
  @Transactional(readOnly = false)
	public int BatchInsert(List<CustomerImport> list, String batchNO, String type, String filename2){
		int successNum=0;
        long begin=System.currentTimeMillis();
        SqlSession session =null;
        int commitCountEveryTime=10000;
                 try {
                     SqlSessionFactory sqlSessionFactory1 = sqlSessionFactoryBean.getObject();
                     session = sqlSessionFactory1.openSession(ExecutorType.BATCH, false);
                     String statement = "com.server.modules.sys.dao.customer.impt.CustomerImportDao.insertBatch";//映射sql的标识字符串
                         int commitCount = (int) Math.ceil(list.size() / (double) commitCountEveryTime);
                         List<CustomerImport> tempList = new ArrayList<CustomerImport>(commitCountEveryTime);
                         int start, stop;
                         Long startTime = System.currentTimeMillis();
                         for (int i = 0; i < commitCount; i++) {
                                 tempList.clear();
                                 start = i * commitCountEveryTime;
                                 stop = Math.min(i * commitCountEveryTime + commitCountEveryTime - 1, list.size() - 1);
							 	int insertCount=0;
                                 for (int j = start; j <= stop; j++) {
                                     CustomerImport ci = list.get(j);
									 ci.setIsNewRecord(false);
                                     ci.setBatchNo(batchNO);
                                     ci.setType(type);
                                     ci.setRemarks(filename2);
                                     ci.preInsert();
                                     tempList.add(ci);
									 insertCount++;
                                     }
                                 int j=session.insert(statement, tempList);
								 if(j!=0){
									 successNum+= insertCount;
								 }
                                 session.commit();
                                 session.clearCache();
                             }
                         Long endTime = System.currentTimeMillis();
                         logger.debug("batchCommit耗时：" + (endTime - startTime) + "毫秒");
                     } catch (Exception e) {
                         logger.error("batchCommit error!", e);
                         e.printStackTrace();
                         session.rollback();
                     } finally {
                         if (session != null) {
                                 session.close();
                             }
                     }
        // 结束时间  
        Long end = new Date().getTime();  
        // 耗时  
        System.out.println("插入数据条数 : " + successNum);
        System.out.println("耗时 : " + (end - begin) / 1000 + " s");
        return successNum;
	}

	public String Excel2Data(List<CustomerImport> list, Workbook wb) {
		String type="";
		for (Sheet sheet : wb) {
			int index=1;
			int cellNum =0;
			for (Row row : sheet) {
				//第一行 处理行
				if(index==1){
					for (Cell cell : row) {
						if ("车辆信息".equals(cell.getStringCellValue())) {
							type = StaticDefine.CUSTOMER_IMPORT_TYPE.car;
							break;
						} else if ("房产信息".equals(cell.getStringCellValue())) {
							type = StaticDefine.CUSTOMER_IMPORT_TYPE.house;
							break;
						} else if ("职务".equals(cell.getStringCellValue())) {
							type = StaticDefine.CUSTOMER_IMPORT_TYPE.other;
							break;
						}
						cellNum++;
					}
				}else{
					//其他行
					int index1=0;
					CustomerImport customerImport=new CustomerImport();
					for(short k=0;k<cellNum;k++){
						Cell cell = row.getCell(k);
						if(cell==null){
							index1++;
							continue;
						}
						String val=null;
						if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
							//val =String.valueOf( cell.getNumericCellValue());
							val = NumberToTextConverter.toText(cell.getNumericCellValue());
						}else if (cell.getCellType() == Cell.CELL_TYPE_STRING){
							val =String.valueOf( cell.getStringCellValue());
						}else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA){
							val =String.valueOf( cell.getCellFormula());
						}else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN){
							val =String.valueOf( cell.getBooleanCellValue());
						}else if (cell.getCellType() == Cell.CELL_TYPE_ERROR){
							val ="";
						}
						if (type ==StaticDefine.CUSTOMER_IMPORT_TYPE.car) {
							if(index1==0){
								customerImport.setName(val);
							}else if(index1==1){
								customerImport.setMobile(val);
							}else if(index1==2){
								customerImport.setTel(val);
							}else if(index1==3){
								customerImport.setCarInfo(val);
							}else if(index1==4){
								customerImport.setPlateno(val);
							}else if(index1==5){
								customerImport.setPlatenoRegTime(val);
							}
						} else if (type == StaticDefine.CUSTOMER_IMPORT_TYPE.house) {
							if(index1==0){
								customerImport.setName(val);
							}else if(index1==1){
								customerImport.setMobile(val);
							}else if(index1==2){
								customerImport.setTel(val);
							}else if(index1==3){
								customerImport.setHousePropertyInfo(val);
							}else if(index1==4){
								customerImport.setHousehold(val);
							}else if(index1==5){
								customerImport.setAddr(val);
							}
						} else if (type == StaticDefine.CUSTOMER_IMPORT_TYPE.other) {
							if(index1==0){
								customerImport.setName(val);
							}else if(index1==1){
								customerImport.setMobile(val);
							}else if(index1==2){
								customerImport.setTel(val);
							}else if(index1==3){
								customerImport.setCompany(val);
							}else if(index1==4){
								customerImport.setPost(val);
							}else if(index1==5){
								customerImport.setAddr(val);
							}
						}
						index1++;
					}
					if(customerImport!=null){
						list.add(customerImport);
					}
					
				}
				index++;
			}
		}
		return type;
	}
	
	@Transactional(readOnly = false)
	public Map<String,Object> batchInsertFiles(List<File> files)throws IOException, InstantiationException, IllegalAccessException {
		Map<String, Object> ret = new HashMap<String, Object>();
		StringBuilder failureMsg = new StringBuilder();
		int successNum = 0;
		int failureNum = 0;
		for (File file : files) {
			String fileMD5 = Md5Utils.getFileMD5(file);
			String fileName = file.getName();
			if(!fileName.endsWith(".xls")&&!fileName.endsWith(".xlsx")){
				continue;
			}
			Long begin1 = new Date().getTime();
			InputStream is =  new FileInputStream(file);
			Workbook wb = null;
			if (org.apache.commons.lang3.StringUtils.isBlank(fileName)){
				throw new RuntimeException("导入文档为空!");
			}else if(fileName.toLowerCase().endsWith("xls")){
				wb = new HSSFWorkbook(is);
			}else if(fileName.toLowerCase().endsWith("xlsx")){
				wb = StreamingReader.builder()
						.rowCacheSize(100)    // number of rows to keep in memory (defaults to 10)
						.bufferSize(4096)     // buffer size to use when reading InputStream to file (defaults to 1024)
						.open(is);
			}else{
				wb = new HSSFWorkbook(is);
				throw new RuntimeException("文档格式不正确!");
			}
	     	List<CustomerImport> list=new ArrayList<>();
			String type =Excel2Data(list, wb);
		
			int countByMd5 = customerImportLogService.countByMd5(fileMD5);
       		// 插入日志
			CustomerImportLog customerImportLog = new CustomerImportLog();
			customerImportLog.setType(type);
			if(countByMd5>0){
				failureMsg.append("<br/>导入失败：您上传的文件【" + fileName+ "】已经上传过，请不要重复上传哦");
				ret.put("failureMsg", failureMsg);
				ret.put("successNum", successNum);
				ret.put("failureNum", failureNum);
				customerImportLog.setExpectCount(list.size() + "");
				customerImportLog.setValidCount(successNum + "");
				customerImportLog.setFilesize(file.length()+"");
				  customerImportLog.setMd5(fileMD5);
		     		 customerImportLog.setFilename(fileName);
		     		 customerImportLog.setFileurl(file.getPath());
				customerImportLog.setRemarks("导入失败：文件【" + fileName+ "】已经上传过");
				customerImportLogService.save(customerImportLog);
				continue;
			}
			String batchNO = batchNoService.getBatchNO("1");
			customerImportLog.setBatchNo(batchNO);
			List<CustomerImport> listValid = new ArrayList<CustomerImport>();// 校验后有效的
			failureNum = validateData(failureNum, failureMsg, listValid, list);
			Long end2 = new Date().getTime();
			// 开时时间
			Long begin = new Date().getTime();
			successNum=this.BatchInsert(listValid, batchNO, type, fileName);
			if (list.size()-successNum > 0) {
				failureMsg.insert(0, "，失败 " + (list.size()-successNum) + " 条客户，导入信息如下：");
			}
			customerImportLog.setExpectCount(list.size() + "");
			customerImportLog.setValidCount(successNum + "");
			customerImportLog.setRemarks("导入成功");
			customerImportLog.setFilesize(file.length()+"");
			customerImportLog.setMd5(fileMD5);
	     	customerImportLog.setFilename(fileName);
	     	customerImportLog.setFileurl(file.getPath());
			customerImportLogService.save(customerImportLog);
			// 结束时间
			Long end = new Date().getTime();
			// 耗时
			System.out.println("excel读取并且校验数据cast : " + (end2 - begin1) / 1000F + "s");
			System.out.println("入库操作cast : " + (end - begin) / 1000F + "s");
		}
		if(files.size()>0){
			File file = files.get(0);
		//	file.getpa
			MyFileUtils.deletefile(file.getParentFile().getAbsolutePath());
		}
		ret.put("failureMsg", failureMsg);
		ret.put("successNum", successNum);
		ret.put("failureNum", failureNum);
		return ret;
	}
	
	
	private Map<String, Object> batchInsertCompress(MultipartFile file) throws IllegalStateException, IOException {
		Map<String, Object> ret = new HashMap<String, Object>();
		int successNum = 0;
		int failureNum = 0;
		StringBuilder failureMsg = new StringBuilder();
		String fileName = file.getOriginalFilename();
		// 插入日志
		CustomerImportLog customerImportLog = new CustomerImportLog();
		//customerImportLog.setType(type);
		// 入库
		String batchNO = batchNoService.getBatchNO("1");
		customerImportLog.setBatchNo(batchNO);
		
		//boolean isUploaded = this.uploadCompressFile(file, customerImportLog);
		Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int day = cal.get(Calendar.DATE);
        String dateDir =  year + File.separator + month
                + File.separator + day + File.separator;
        File tmpDir = new File(PathUtils.getSaveImagePath()+dateDir);
        if (!tmpDir.exists()) {
            tmpDir.mkdirs();
        }
        // 构造新的图片名称
        String savePath = PathUtils.getSaveImagePath()+ dateDir ;
        String fileN= System.currentTimeMillis()+fileName;
        File targetFile = new File(savePath,fileN);  
         if(!targetFile.exists()){  
             targetFile.mkdirs();  
         }  
         try {
        	//上传压缩文件
    		 file.transferTo(targetFile); 
			} catch (Exception e) {
				 String fileMD5 = Md5Utils.getFileMD5(targetFile);
				 customerImportLog.setMd5(fileMD5);
        		 failureMsg.append("<br/>导入失败：您上传的文件【" + fileName+ "】已经上传过，请不要重复上传哦");
 				ret.put("failureMsg", failureMsg);
 				ret.put("successNum", successNum);
 				ret.put("failureNum", failureNum);
 			//	customerImportLog.setExpectCount(ei.getLastDataRowNum() + "");
 				customerImportLog.setValidCount(successNum + "");
 				customerImportLog.setRemarks("导入失败：文件【" + fileName+ "】已经上传过");
 				customerImportLog.setMd5(Md5Utils.getFileMD5(targetFile));
 				customerImportLogService.save(customerImportLog);
 				return ret;
		}
       
         //保存  
         try {  
        	 String fileMD5 = Md5Utils.getFileMD5(targetFile);
        	 int countByMd5 = customerImportLogService.countByMd5(fileMD5);
        	 //之前上传过
        	 if(countByMd5>0){
        		 customerImportLog.setMd5(fileMD5);
        		 failureMsg.append("<br/>导入失败：您上传的文件【" + fileName+ "】已经上传过，请不要重复上传哦");
 				ret.put("failureMsg", failureMsg);
 				ret.put("successNum", successNum);
 				ret.put("failureNum", failureNum);
 			//	customerImportLog.setExpectCount(ei.getLastDataRowNum() + "");
 				customerImportLog.setValidCount(successNum + "");
 				customerImportLog.setRemarks("导入失败：文件【" + fileName+ "】已经上传过");
 				customerImportLog.setMd5(Md5Utils.getFileMD5(targetFile));
 				customerImportLogService.save(customerImportLog);
 				return ret;
        	 }else{
        		 
        		 //解压rar文件
        		 if(ExtractUtils.extractRarFiles(targetFile)){
        			 //获取解压缩后的文件  进行操作
        			 String[] split = targetFile.getName().split("\\.");
        			 List<File> readfile = MyFileUtils.readfile(savePath+File.separator+split[0],null);
        			 customerImportLog.setMd5(fileMD5);
    	     		 customerImportLog.setFilename(fileName);
    	     		 customerImportLog.setFilesize(file.getSize()+"");
    	     		 customerImportLog.setFileurl(targetFile.getPath());
    	     		customerImportLogService.save(customerImportLog);
        			 return this.batchInsertFiles(readfile);
        		 }
        		 //解压zip文件
        		 else if(ExtractUtils.extractZipFiles(targetFile)){
        			 String[] split = targetFile.getName().split("\\.");
        			 List<File> readfile = MyFileUtils.readfile(savePath+File.separator+split[0],null);
        			 customerImportLog.setMd5(fileMD5);
    	     		 customerImportLog.setFilename(fileName);
    	     		 customerImportLog.setFilesize(file.getSize()+"");
    	     		 customerImportLog.setFileurl(targetFile.getPath());
    	     		 customerImportLogService.save(customerImportLog);
        			 return  this.batchInsertFiles(readfile);
        		 }
	             
        	 }
        	 
         } catch (Exception e) {  
             e.printStackTrace();  
         } finally {
		} 
		 return ret;
	}



	

	@Transactional(readOnly = false)
	public ImportTempObj batchMQInsert(MultipartFile file) throws  IOException, InstantiationException, IllegalAccessException, InterruptedException {
		ImportTempObj ret=new ImportTempObj();
	//	ProducerUtils.produceAnalyzeExcelMulFile(file,StaticDefine.CUSTOMER_IMPORT_MQ_TYPE.IMPORT_ANALYZEEXCEL_MQ);
		return ret;
	}


	public int validateData(int failureNum, StringBuilder failureMsg,List<CustomerImport> listValid, List<CustomerImport> list) {
        //数据库已存在的手机号
        Map<String,Boolean> moblieMap=new HashMap<>();

        List<CustomerImport> temp=new ArrayList<>();
        List<String> mobiles=new ArrayList<>();
        for (CustomerImport customerImport : list) {
            //手机号校验
            String tel = customerImport.getTel();
            String mobile=customerImport.getMobile();
            if (StringUtils.isBlank(mobile)||StringUtils.isBlank(mobile.replaceAll("[ |　]", " ").trim())) {
                if(failureNum<10){
                    failureMsg.append("<br/>客户（ " + customerImport.getName()+ " ）的手机号为空，无法导入; ");
                }
                failureNum++;
                continue;
            }

            mobile=mobile.replaceAll("[ |　]", " ").trim();
            boolean isMobileSeted=false;
            if(RegexUtils.checkMobile(mobile)){
                customerImport.setMobile(mobile);
                isMobileSeted=true;
            }
            if(StringUtils.isBlank(tel)&&RegexUtils.checkPhone(mobile)){
                customerImport.setTel(mobile);
            }

            //可能会有手机座机连在一起的  斜杠，空格，还有@符号  需要字符串切割
            String[] split0 = mobile.split("/");

            if(split0.length>1){
                for (int i = 0; i < split0.length; i++) {
                    String split=split0[i];
                    if(RegexUtils.checkMobile(split)){
                        customerImport.setMobile(split);
                        isMobileSeted=true;
                    }
                    if(StringUtils.isBlank(tel)&&RegexUtils.checkPhone(split)){
                        customerImport.setTel(split);
                    }
                }
            }
            if(!isMobileSeted){
                String[] split1 = mobile.split("\\\\");
                if(split1.length>1){
                    for (int i = 0; i < split1.length; i++) {
                        String split=split1[i];
                        if(RegexUtils.checkMobile(split)){
                            customerImport.setMobile(split);
                            isMobileSeted=true;
                        }
                        if(StringUtils.isBlank(tel)&&RegexUtils.checkPhone(split)){
                            customerImport.setTel(split);
                        }
                    }
                }
            }
            if(!isMobileSeted){
                String[] split2 = mobile.split("@");
                if(split2.length>1){
                    for (int i = 0; i < split2.length; i++) {
                        String split=split2[i];
                        if(RegexUtils.checkMobile(split)){
                            customerImport.setMobile(split);
                            isMobileSeted=true;
                        }
                        if(StringUtils.isBlank(tel)&&RegexUtils.checkPhone(split)){
                            customerImport.setTel(split);
                        }
                    }
                }
            }
            if(!isMobileSeted){
                String[] split3 = mobile.split("\\s+");
                if(split3.length>1){
                    for (int i = 0; i < split3.length; i++) {
                        String split=split3[i];
                        if(RegexUtils.checkMobile(split)){
                            customerImport.setMobile(split);
                            isMobileSeted=true;
                        }
                        if(StringUtils.isBlank(tel)&&RegexUtils.checkPhone(split)){
                            customerImport.setTel(split);
                        }
                    }
                }
            }
            if(!isMobileSeted){
                if(failureNum<10){
                    failureMsg.append("<br/>客户（ " + customerImport.getName()+ " ）的手机号【" + customerImport.getMobile()+ "】不合法; ");
                }
                failureNum++;
                continue;
            }
            if (StringUtils.isNotBlank(customerImport.getMobile())) {
                temp.add(customerImport);
                mobiles.add(customerImport.getMobile());
            }
        }
        if(CollectionUtils.isEmpty(temp)){
            return list.size();
        }
        //TODO  list太大内存溢出
        List<CustomerImport> existMobiles = dao.findByMobileIn(mobiles);
        if(!CollectionUtils.isEmpty(existMobiles)){
            for (CustomerImport customerImport : existMobiles ) {
                moblieMap.put(customerImport.getMobile(),true);
            }
        }

		for (CustomerImport customerImport : temp) {
            String mobile = customerImport.getMobile();
			if(moblieMap.containsKey(mobile)){
				if(failureNum<10){
					failureMsg.append("<br/>客户（ " + customerImport.getName()+ " ）的手机号【" +mobile+ "】已存在; ");
				}
				failureNum++;
				continue;
			}
            moblieMap.put(mobile, true);
			String name = customerImport.getName();
			//性别判断
			if(StringUtils.isNotBlank(name)&&name.contains("先生")){
				customerImport.setName(name.replaceAll("先生", ""));
				customerImport.setGender("1");
			}
			else if(StringUtils.isNotBlank(name)&&name.contains("女士")){
				customerImport.setName(name.replaceAll("女士", ""));
				customerImport.setGender("2");
			}
			try {

				//这里每次都查数据库比较耗时  考虑用缓存
				//TODO
			/*	Integer byMobile = this.getByMobile(mobile);
				if (byMobile < 1) {
					// successNum++;
				} else {
					failureMsg.append("<br/>客户（ " + customerImport.getName()+ " ）的手机号【" + customerImport.getMobile()+ "】已存在; ");
					failureNum++;
				}*/
				listValid.add(customerImport);
			} catch (ConstraintViolationException ex) {
				if(failureNum<10){
					failureMsg.append("<br/>客户：（ " + customerImport.getName() + ":"+ customerImport.getMobile() + "） 导入失败：");
				}
				List<String> messageList = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
				for (String message : messageList) {
					failureMsg.append(message + "; ");
					failureNum++;
				}
			} catch (Exception ex) {
				if(failureNum<10){
					failureMsg.append("<br/>客户：（ " + customerImport.getName() + ":"+ customerImport.getMobile() + "） 导入失败："+ ex.getMessage());
				}
				
			}
		}
		return failureNum;
	}
	
	    @Transactional(readOnly = false)
	    public boolean uploadFile(MultipartFile file,CustomerImportLog customerImportLog) {
	        Calendar cal = Calendar.getInstance();
	        int year = cal.get(Calendar.YEAR);
	        int month = cal.get(Calendar.MONTH) + 1;
	        int day = cal.get(Calendar.DATE);
	        String dateDir =  year + File.separator + month
	                + File.separator + day + File.separator;
	        File tmpDir = new File(PathUtils.getSaveImagePath()+dateDir);
	        if (!tmpDir.exists()) {
	            tmpDir.mkdirs();
	        }
	        // 构造新的图片名称
	        String fileName = file.getOriginalFilename() ;  
	        String savePath = PathUtils.getSaveImagePath()+ dateDir ;
	        File targetFile = new File(savePath, fileName);  
	         if(!targetFile.exists()){  
	             targetFile.mkdirs();  
	         }  
	         //保存  
	         try {
				 file.transferTo(targetFile);
				 String fileMD5 = Md5Utils.getFileMD5(targetFile);
	        	 int countByMd5 = customerImportLogService.countByMd5(fileMD5);
	        	 //之前上传过
	        	 if(countByMd5>0){
					 customerImportLog.setMd5(fileMD5);
					 customerImportLog.setFilename(fileName);
					 customerImportLog.setFilesize(file.getSize()+"");
					 customerImportLog.setFileurl(targetFile.getPath());
	        		 return false;
	        	 }else{
		             customerImportLog.setMd5(fileMD5);
		     		 customerImportLog.setFilename(fileName);
		     		 customerImportLog.setFilesize(file.getSize()+"");
		     		 customerImportLog.setFileurl(targetFile.getPath());
		     		 return true; 
	        	 }
	        	 
	         } catch (Exception e) {  
	             e.printStackTrace();  
	         } finally {
			} 
	         return false;
	      
	    }
	    
	    @Transactional(readOnly = false)
	    public boolean uploadCompressFile(MultipartFile file,CustomerImportLog customerImportLog) {
	        
	         return false;
	      
	    }
	
}